package com.hyt.it.ogt.kq.service.gov.schedule.utils;

import static org.mockito.ArgumentMatchers.contains;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import com.hyt.it.ogt.kq.service.gov.schedule.model.ScheduleExamRoom;
import com.hyt.it.ogt.kq.service.gov.schedule.model.ScheduleExamRoom.ScheduleCandidate;

public class FineTuneUtils {
    /***
     * 对单科目，不保持考生座位的考场进行调整，将没有达到考场容量的考场从其它考场进行填充
     * 
     * @param list
     * @return
     */
    public static List<ScheduleExamRoom> fineTuneSingleAndNoMainTen(List<ScheduleExamRoom> preRooms) {
        List<ScheduleExamRoom> fineTuneRooms = preRooms.stream()
                .filter(item -> (item.getCapacity() - item.getCandidates().size()) == 0).collect(Collectors.toList());
        // 需要调整的考场
        List<ScheduleExamRoom> needTuneRooms = preRooms.stream()
                .filter(item -> (item.getCapacity() - item.getCandidates().size()) > 0).collect(Collectors.toList());
        needTuneRooms = needTuneRooms.stream().filter(item -> (item.getCandidates().size() > 0))
                .collect(Collectors.toList());
        needTuneRooms = needTuneRooms.stream()
                .sorted(Comparator.comparingInt(item -> (item.getCapacity() - item.getCandidates().size())))
                .collect(Collectors.toList());
        int roomIndex = 0;
        for (ScheduleExamRoom examRoom : needTuneRooms) {
            if (examRoom.getCandidates().size() == examRoom.getCapacity()) {
                continue;
            }
            String subject = null;
            if (examRoom.getCandidates().size() != 0) {
                subject = examRoom.getCandidates().get(0).getSubject();
            } else {
                subject = findNeedShiftSubject(needTuneRooms.subList(roomIndex, needTuneRooms.size()),
                        examRoom.getCapacity());
            }

            if (subject == null) {
                break;
            }

            shiftCandidate(examRoom, needTuneRooms.subList(roomIndex, needTuneRooms.size()), subject);
            for (int index = 0; index < examRoom.getCandidates().size(); index++) {
                examRoom.getCandidates().get(index).setPosition(index + 1);
            }
            roomIndex = roomIndex + 1;
        }
        needTuneRooms = needTuneRooms.stream().filter(item -> (item.getCandidates().size() > 0))
                .collect(Collectors.toList());
        fineTuneRooms.addAll(needTuneRooms);
        return fineTuneRooms;
    }

    // 转移考生
    public static void shiftCandidate(ScheduleExamRoom examRoom, List<ScheduleExamRoom> totalExamRooms,
            String subject) {
        int needCandidateNumber = examRoom.getCapacity() - examRoom.getCandidates().size();
        List<ScheduleExamRoom> totalExamRoomList = totalExamRooms.stream()
                .filter(item -> item.getCandidates().size() > 0).collect(Collectors.toList());

        totalExamRoomList = totalExamRoomList.stream()
                .sorted(Comparator.comparingInt(item -> item.getCandidates().size()))
                .collect(Collectors.toList());
        for (ScheduleExamRoom item : totalExamRoomList) {
            if (needCandidateNumber == 0) {
                break;
            }
            if (item.getRoomId().equalsIgnoreCase(examRoom.getRoomId())) {
                continue;
            }

            if (item.getCandidates().size() == item.getCapacity()) {
                continue;
            }

            if (item.getCandidates().size() == 0
                    || !item.getCandidates().get(0).getSubject().equalsIgnoreCase(subject)) {
                continue;
            }

            List<ScheduleCandidate> cacheCandidates = new ArrayList<ScheduleCandidate>();
            for (ScheduleCandidate candidate : item.getCandidates()) {
                if (needCandidateNumber == 0) {
                    break;
                }
                candidate.setRoomId(examRoom.getRoomId());
                examRoom.getCandidates().add(candidate);
                cacheCandidates.add(candidate);
                needCandidateNumber = needCandidateNumber - 1;
            }
            cacheCandidates.stream().forEach(cacheItem -> {
                item.getCandidates().remove(cacheItem);
            });
        }
    }

    public static String findNeedShiftSubject(List<ScheduleExamRoom> needTuneExamRooms, int roomSize) {
        String subject = null;
        List<ScheduleExamRoom> scheduleExamRoomList = needTuneExamRooms.stream()
                .filter(item -> item.getCandidates().size() > 0).collect(Collectors.toList());
        if (scheduleExamRoomList.size() > 0) {
            scheduleExamRoomList = scheduleExamRoomList.stream()
                    .sorted(Comparator.comparingInt(item -> item.getCandidates().size()))
                    .collect(Collectors.toList());
            subject = scheduleExamRoomList.get(0).getCandidates().get(0).getSubject();
        }
        return subject;
    }

}
